package com.xujl.task;

import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.Callable;

/**
 * <pre>
 *     @author : xujl
 *     e-mail : 597355068@qq.com
 *     time   : 2018/7/24
 *     desc   :
 *     version: 1.0
 * </pre>
 */
public class TaskCallable<T> implements Callable<T>, Observer {
    protected static final String TAG = "TaskThread";
    private Task<?> task;
    private String taskId;

    public TaskCallable (Task<?> task) {
        setTask(task);
    }

    public TaskCallable () {
    }

    public void setTask (Task<?> task) {
        this.task = task;
        taskId = task.getTaskId();
        task.addObserver(this);
    }

    @Override
    final public T call () throws Exception {
        RxLog.d(TAG, "threadId:" + Thread.currentThread().getId() + "&&taskId:" + taskId);
        if (isTaskNull()) {
            RxLog.e(TAG, "call:task==null");
            return null;
        }
        task.setTaskState(Task.STATE_RUNNING);
        //任务是否正常完成
        boolean isCompete = true;
        try {
            /*优先执行当前子类run(emitter)方法，如果
            当前方法返回false,表示没有任务则再去执行Task的run方法
             */
            final boolean isFinish = run(getEmitter());
            if (!isFinish && getTask() != null) {
                getTask().run(getEmitter());
            }
        } catch (Exception e) {
            isCompete = false;
            RxLog.e(TAG, "任务执行异常：", e);
            if (getEmitter() != null) {
                getEmitter().error(e);
            }
        }
        if (isCompete && getEmitter() != null) {
            getEmitter().finish();
        }
        return null;
    }


    /**
     * 任务是否存在
     *
     * @return
     */
    private boolean isTaskNull () {
        return this.task == null;
    }

    private Emitter getEmitter () {
        return task.getEmitter();
    }

    private Task getTask () {
        return task;
    }

    /**
     * 子线程方法
     *
     * @param emitter
     * @return 是否被复写
     */
    public boolean run (Emitter emitter) throws Exception {
        return false;
    }

    @Override
    protected void finalize () throws Throwable {
        RxLog.i(TAG, taskId + ":即将被回收");
        super.finalize();

    }

    @Override
    public void update (Observable o, Object arg) {
        if (Task.STATE_DESTROY.equals(arg)) {
            RxLog.d(TAG, taskId + ":任务已销毁，解除thread绑定");
            task = null;
        }
    }
}
